home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-06-03 | 5.1 KB | 119 lines | [TEXT/CWIE] |
- // CKeywords.h
- //
- // A base class that stores an arbitrary number of keywords and
- // associated indexes to objects attached to keywords. Multiple
- // indexes are associated with each keyword.
- //
- // This class uses Handles to store the keywords in large blocks.
- // It does not provide a way to change the storge mechanism
-
- enum {
- kCharsInFirstKeywordlock = 28,
- kMaxKeywordsPerPage = 100,
- kBlockMapKeywordsPerPageLimit = 384, // NEVER EXCEED THIS ABOVE!!!
-
- kBitsInALong = 32 // It only seems self-evident
- };
-
-
- // First of all, we do some tricky stuff with the KeywordHolder
- // record. A keyword will usually fit within a single record,
- // but if it is longer than 28 bytes, we use the next holder
- // block as a continuation block, so the first 4 bytes of that
- // block are meaningless. This allows a keyword of 60 bytes to ft
- // into just two blocks. The benefit of this scheme is that we can
- // preallocate chunks of memory for keyword storage for maximum speed
- // but we can still keep the wasted space fairly low. 1000 small keywords
- // will only take 32K of memory.
-
- typedef struct {
- short blockCount;
- short length; // bytes of text in this keyword
- char keywordData[kCharsInFirstKeywordlock];// Pad the keyword size to 32 bytes
- } KeywordHolder, *KeywordHolderP, **KeywordHolderH;
-
-
- // There is an important note about this structure. The last block
- // (or possibly more) may be left blank if the keyword being added
- // required more blocks than were available in this page.
- // A Page in this context is the header and keywords stored in a
- // single block. It does not actually correspond to a page of VM.
-
- typedef struct KeywordPage {
- KeywordPage** nextPage; // Handle to next block of keywords
- long firstKeywordID; // First ID for this page
- long keywordsInPage; // How many occupy this page?
- long firstFreeSlot; // First unused block on this page
- long lastOnPage; // last used block on the page
- // char blockMap[kMaxKeywordsPerPage];
- unsigned long blockMap[12]; // 384 bits, 1 per keyword block (limits
- // us to a Maximum page size of 12320 bytes)
- KeywordHolder keywords[kMaxKeywordsPerPage];
- } KeywordPage, *KeywordPageP, **KeywordPageH;
-
- // Reference Info. Each Keyword can be assigned to one or more objects
- // outside this class. When you attach a keyword to an object you can
- // attach the reference inside the CKeywords object. This allows for
- // very fast "searching" for all items with a given keyword. You can
- // just retrieve the references for any given keyword and you are done.
- // The structure for the reference is a user defined number of longs that
- // will be associated with the given keyword.
- class CKeywords
- {
- long fTotalKeywords;
- short fLongsPerReferenceItem; // # of longs in a reference
- unsigned short fReferenceBlockSize;
- KeywordPageH fFirstKeywordBlock;
- Boolean fReuseEmptyHoles; // if false, IDs will not be reused
-
- public:
- CKeywords(short longsPerReferenceItem = 1, Boolean reuseHoles = false);
- ~CKeywords(void);
-
- virtual long GetKeywordCount(void);
- virtual long GetKeywordReferenceCount(long keywordID);
- /******************************************************************************/
- virtual long GetKeywordReferenceCount(char* theKeyword, short keyLength,
- Boolean partialMatch = false);
-
- virtual long FindKeywordID(char* theKeyword, short keyLength,
- Boolean partialMatch = false);
-
- virtual long FindKeywordIDInRange(long startID, long endID,
- char* theKeyword, short keyLength,
- Boolean partialMatch = false);
-
- // Look up a keyword and return the length and data. Be sure you
- // have enough storage allocted! To just get length, pass nil for
- // the keyOut parameter.
- virtual short GetKeywordByID(long keywordID, char* keyOut);
-
- // The following routines are used to add keywords
- virtual long AddKeyword(char* theKeyword, short keyLength);
- virtual Boolean AddKeywordReference(long keywordID, long* keyReferenceBlock,
- short referenceCount = 1);
- virtual void AddReferenceToAllKeywords(long *keyReferenceBlock);
-
- // And of course you might want to delete a keyword
- virtual void DeleteKeywordID(long keywordID);
- virtual void DeleteKeywordReference(long keywordID, long* keyReferenceBlock);
- virtual void DeleteAllReferenceMatch(long *keyReferenceBlock);
- virtual void DeleteAllReferences(void);
-
- // Use this with extreme caution! It nukes references, keyword, everything
- virtual void DeleteAllKeywords(void);
-
- protected:
- virtual KeywordPageH CreateEmptyPage(long firstID);
- virtual Boolean GetPageN(short whichPage, KeywordPageH *outHand, Boolean createIt);
- virtual void FindAvailableSlot(short requiredBlocks, KeywordPageH *outPage,
- short *pageIndex, short *pageNumber);
- virtual short FindSlotsOnPage(KeywordPageH currentPage, short blocksRequired);
-
- // A current limitation of UpdateBlock map prevents more than 2 longs from being
- // set in the block map. This means you shouldn't have more than 33 keyword blocks
- // set or you could fail and corrupt your blocks. (Of course this is 1052 characters)
- virtual void UpdateBlockMap(KeywordPageH thePage, short firstBlock, short count,
- Boolean turnOn);
- };
-